#include "thread_pool.hpp"
#include <iostream>
#include <chrono>
#include <string>
#include <vector> // for std::vector

// 具体的任务类
class MyTask {
public:
    explicit MyTask(int id, int sleep_ms, const std::string& name = "GenericTask") 
        : m_id(id), m_sleep_ms(sleep_ms), m_name(name) {}

    void process() {
        std::cout << "[" << m_name << " " << m_id << "] starting on thread " 
                  << std::this_thread::get_id() << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(m_sleep_ms));
        std::cout << "[" << m_name << " " << m_id << "] finished on thread " 
                  << std::this_thread::get_id() << std::endl;
    }
private:
    int m_id;
    int m_sleep_ms;
    std::string m_name;
};

class CriticalTask {
public:
    explicit CriticalTask(int id) : m_id(id) {}
    void process() {
        std::cout << "[CriticalTask " << m_id << "] executing..." << std::endl;
        // 模拟一些重要但快速的操作
    }
private:
    int m_id;
};


int main() {
    std::cout << "--- C++ Thread Pool Test ---" << std::endl;

    // 1. 基本功能测试：创建、启动、添加任务、停止
    std::cout << "\n--- Test Case 1: Basic Functionality (4 threads, 10 queue) ---" << std::endl;
    ThreadPool pool(4, 10); // 4个线程，任务队列大小10
    pool.start(); // 显式启动线程池

    std::cout << "Adding 7 tasks..." << std::endl;
    for (int i = 0; i < 7; ++i) {
        // 使用 std::make_unique 创建 Task 对象，并传递给 addTask
        //pool.addTask(std::make_unique<MyTask>(i, 200, "MyTask #" + std::to_string(i)));
        pool.addTask(std::make_unique<std::function<void()>>(std::bind(&MyTask::process, MyTask(i, 200, "MyTask #" + std::to_string(i)))));

    }
    std::cout << "Waiting for some tasks to complete before stopping..." << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(1)); // 等待1秒，让部分任务执行

    std::cout << "Stopping thread pool gracefully..." << std::endl;
    pool.stop(); // 显式优雅关闭
    std::cout << "Thread pool gracefully shutdown." << std::endl;


    // 2. 立即关闭测试
    std::cout << "\n--- Test Case 2: Immediate Shutdown (2 threads, 5 queue) ---" << std::endl;
    ThreadPool pool_immediate(2, 5); // 2个线程，任务队列大小5
    pool_immediate.start();

    std::cout << "Enqueuing many long tasks (some will be aborted)..." << std::endl;
    for (int i = 0; i < 8; ++i) { // 尝试添加超过队列容量的任务
        try {
            //pool_immediate.addTask(std::make_unique<MyTask>(100 + i, 500, "LongTask #" + std::to_string(100+i)));     
            pool_immediate.addTask(std::make_unique<std::function<void()>>(std::bind(&MyTask::process, MyTask(100 + i, 500, "LongTask #" + std::to_string(100+i)))));
        } catch (const std::runtime_error& e) {
            std::cerr << "  Failed to add task " << (100 + i) << ": " << e.what() << std::endl;
        }
    }

    std::this_thread::sleep_for(std::chrono::milliseconds(200)); 
    std::cout << "Calling immediate shutdown..." << std::endl;
    pool_immediate.shutdown_immediate(); // 立即关闭
    std::cout << "Immediate shutdown completed. Remaining tasks should be aborted." << std::endl;


    // 3. 队列满抛异常测试
    std::cout << "\n--- Test Case 3: Queue Full Exception (1 thread, 2 queue) ---" << std::endl;
    ThreadPool pool_full_test(1, 2);
    pool_full_test.start();
    try {
        //pool_full_test.addTask(std::make_unique<CriticalTask>(1));
        //pool_full_test.addTask(std::make_unique<CriticalTask>(2));
        pool_full_test.addTask(std::make_unique<std::function<void()>>(std::bind(&CriticalTask::process, CriticalTask(1))));
        pool_full_test.addTask(std::make_unique<std::function<void()>>(std::bind(&CriticalTask::process, CriticalTask(2))));
        std::cout << "Queue has 2 tasks." << std::endl;
        // 队列已满，尝试添加第三个任务
        //pool_full_test.addTask(std::make_unique<CriticalTask>(3)); // 预期抛出异常                                          
        pool_full_test.addTask(std::make_unique<std::function<void()>>(std::bind(&CriticalTask::process, CriticalTask(3))));
        std::cout << "Unexpected: Added 3rd task to full queue." << std::endl;
    } catch (const std::runtime_error& e) {
        std::cerr << "Caught expected exception: " << e.what() << std::endl;
    }
    pool_full_test.stop();
    std::cout << "Test Case 3 finished." << std::endl;


    std::cout << "\n--- All tests finished ---" << std::endl;
    return 0;
}
